#include "automation.h"
#include "iaction.h"
#include <QApplication>

Automation::Automation()
    : state_(Stopped)
    , beginning_(NULL)
    , current_(NULL)
    , curAccount_(0)
{

}

Automation::~Automation()
{

}

void Automation::initChain(QString acc, QString psw)
{
//    ActionFindWindow *afw0 = new ActionFindWindow();
//    afw0->matchClass("TXGuiFoundation");
//    afw0->matchTitle("QQ");
//    afw0->setAction(AWClose);
//    beginning_ = afw0;
//    return;

    ActionProcess *ap = new ActionProcess("C:\\Program Files (x86)\\Tencent\\QQLite\\Bin\\QQScLauncher.exe");
    ActionFindQQLogin *af = new ActionFindQQLogin(495,470);
    /* */ActionWait *aw = new ActionWait(500,af);  aw->setPrev(af,1); //af未找到，进aw等待.
    //定位到账号框
    ActionRelativePos *ar = new ActionRelativePos(278,278);  ar->setPrev(af);
    ActionWait *aw2 = new ActionWait(); aw2->setWaitMs(1000);
    ActionMouse *am = new ActionMouse(IAActClick);
    ActionCompositeKey *ac = new ActionCompositeKey(ACKSelectAll);
    ActionInput *ai = new ActionInput(acc,false);

    //定位到密码框
    ActionRelativePos *ar2 = new ActionRelativePos(278,305);
    ActionMouse *am2 = new ActionMouse(IAActClick);
    ActionInput *ai2 = new ActionInput(psw,false);

    //定位到登录按钮 稍等500ms
    ActionRelativePos *ar3 = new ActionRelativePos(278,371);
    ActionMouse *am3 = new ActionMouse(IAActClick);
    ActionWait *aw4 = new ActionWait(); aw4->setWaitMs(500);

    //检查登录窗.0没找到则继续主流程;1登录框;2
    ActionQQLogin *aqq = new ActionQQLogin();
    ActionWait *aw5 = new ActionWait(500,aqq);
    aqq->setNext(aw5,1);//aqq->setNext(ar,1);  //1转去输入账号密码
    aqq->setNext(aw5,2);  //2验证码输入,等待
    aqq->setNext(aw5,5);  //4其他界面,等待

    ActionFindWindow *afw = new ActionFindWindow();
    afw->matchClass("TXGuiFoundation");
    afw->matchTitle("QQ");
    afw->setAction(AWClose);
    aqq->setNext(afw,3);  //3密码错误,关掉窗口返回第一步重来.
    aqq->setNext(afw,4);  //4找回界面,关掉窗口返回第一步重来.
    afw->setNext(ap); afw->setNext(ap,1);  //应该不可能由1跳去ap

    //杀掉TxPlatform,等待2秒,结束.
    ActionKill *ak = new ActionKill("TXPlatform"); ak->setPrev(aqq);
    //ActionWait *aw3 = new ActionWait(); aw3->setWaitMs(2000);

    //检查其他QQ窗口,将其隐藏.
    ActionFindWindow *afw2 = new ActionFindWindow();
    afw2->matchClass("TXGuiFoundation");
    afw2->matchTitle("QQ");
    afw2->setAction(AWMini);
    //afw2找到进aw6等待后afw2再找一次. 没找到则结束.
    ActionWait *aw6 = new ActionWait(); aw6->setWaitMs(500);
    aw6->setNext(afw2);

    beginning_ = ap;
}

void Automation::doStart()
{
    current_ = NULL;
    curAccount_ = 0;
    if(accounts_.count() < 2){
        emit sigFinished();
        return;
    }
    state_ = Running;
    progress();
}

void Automation::doPause()
{
    state_ = Paused;
}

void Automation::doStop()
{
    state_ = Stopped;
    curAccount_ = 0;
    current_ = NULL;
}

void Automation::doResume()
{
    state_ = Running;
    progress();
}

void Automation::progress()
{
    do
    {
        if(current_ == NULL)
        {
            if(!nextAccount())
            {
                emit sigFinished();
                return;
            }
        }

        int ret = current_->doExec();
        if(ret == -2){ //hold
            emit sigHold(current_->msg());
            break;
        }
        else if(ret == -1){
            emit sigHalt(current_->msg());
            break;
        }
        else{
            current_ = current_->getNext(ret);
            if(current_ == NULL){
                if(!nextAccount())
                {
                    emit sigFinished();
                    return;
                }
            }
        }

        QApplication::processEvents();
    }
    while(current_ && state_ == Running);
}

void Automation::setAccount(const QStringList &accounts)
{
    accounts_ = accounts;
}

bool Automation::nextAccount()
{
    IAction::freeAllActions();
    if(accounts_.count()>=(curAccount_+1)*2)
    {
        QString acc = accounts_.at(curAccount_*2);
        QString psw = accounts_.at(curAccount_*2+1);
        qInfo()<<"==Start== ["<<curAccount_<<"]"<<acc<<psw;
        ++ curAccount_;
        initChain(acc,psw);
        current_ = beginning_;
        return true;
    }
    else
    {
        return false;
    }
}
